Another aspect of the graphics environment that affects the way QuickTime displays images on the screen is the characteristics of the graphics device on which they're being presented. These include such things as the device's pixel resolution, its color depth, and the capacity of its color table. The device's characteristics are summarized in a graphics device record (described in detail in Mac OS For QuickTime Programmers.
Ordinarily, the results of a program's drawing operations depend on the graphical capabilities of the display device that happens to be connected to the user's computer at run time. There can even be more than one such device attached to the same system: QTML will figure out which screen is being drawn to and will display all results correctly according to the characteristics of each device. All of this normally happens automatically, and is transparent to the running program.
Sometimes, however, a program may need to take a more active role in controlling the graphics environment for its drawing operations. If you're creating a QuickTime movie, for instance, you probably don't want to define the movie's appearance in terms of the display characteristics of a particular graphics device. Rather, you want the movie's content to be device-independent, with its own inherent dimensions, pixel depth, colors, and so on. Then, when the movie is displayed on a user's computer, QuickTime will automatically adapt its graphical characteristics to those of the available display device, and will present the movie as faithfully as it can on the given device.
The way to accomplish this is to define the movie with respect to a device-independent graphics world . This combines a graphics port and a device record, which together completely determine the graphics environment in which QuickTime does its drawing. Like the window record we discussed in the preceding section, the data structure representing a graphics world is an extended graphics port with some additional fields appended at the end. The exact details are private to QTML; the graphics world is always referred to by means of an opaque pointer of type GWorldPtr . Because the underlying structure is based on a graphics port, however, this pointer is equated to a graphics port pointer:
typedef CGrafPtr GWorldPtr;
This means that (again like a window record), a graphics world can be used anywhere a graphics port would be expected: for instance, as an argument to the MacSetPort function that sets the current port for subsequent drawing operations.
A graphics world's device record can represent an existing physical graphics device, but it need not: it can also describe a fictitious "offscreen" device with any graphical characteristics you choose. You create such an offscreen graphics world by specifying the desired characteristics as parameters to the QTML function NewGWorld :
QDErr
NewGWorld
(GWorldPtr *offscreenGWorld, // Returns pointer to GWorld
short pixelDepth, // Color depth in bits per pixel
const Rect *boundsRect, // Boundary rectangle
CTabHandle cTable, // Handle to color table
GDHandle aGDevice, // Set to null for offscreen
GWorldFlags flags); // Option flags
You can read all about this function and its parameters in Mac OS For QuickTime Programmers. What's relevant here is that if the noNewDevice flag in the flags parameter is clear, the function will ignore the parameter aGDevice and create a new, device-independent device record with the specified characteristics. It will then combine this device record with a graphics port for drawing into a memory-based image buffer (rather than directly to the screen), and will return a pointer to the resulting graphics world via the offscreenGWorld parameter.
Note, however, that when you use NewGWorld to create your graphics world, it will be set up to draw into a Macintosh-style bitmap as its image buffer. If you want to work with a Windows-style bitmap instead, you can use an alternate function available only in the Windows version of the QuickTime API:
QDErr
NewGWorldFromHBITMAP
(GWorldPtr *offscreenGWorld, // Returns pointer to GWorld
CTabHandle cTable, // Handle to color table
GDHandle aGDevice, // Set to null for offscreen
GWorldFlags flags, // Option flags
void *newHBITMAP, // Handle to bitmap
void *newHDC) // Handle to device context
long rowBytes) // number of bytes in a
scanline
The parameters newHBITMAP and newHDC must either both be null or handles to a Windows bitmap and device context, respectively. If they're null, the function will allocate a complete graphics world for you; otherwise, it will simply wrap one around the specified structures. This allows you to use the native Windows drawing environment as the source for QuickTime operations such as image compression or CopyBits . If you do supply a Windows bitmap, it must be a device-independent bitmap (DIB) created with the Windows function CreateDIBSection . All other parameters are as described in Mac OS For QuickTime Programmers, with the exception of the pixelFormat parameter that replaces pixelDepth in the original NewGWorld function. Valid settings for this parameter are as follows:
0 // Default
k1MonochromePixelFormat
k2IndexedPixelFormat
k4IndexedPixelFormat
k8IndexedPixelFormat
k1IndexedGrayPixelFormat
k2IndexedGrayPixelFormat
k4IndexedGrayPixelFormat
k8IndexedGrayPixelFormat
k16BE555PixelFormat
k32ARGBPixelFormat
k16LE555PixelFormat
k16LE565PixelFormat
k24BGRPixelFormat
k24RGBPixelFormat
k32BGRAPixelFormat
k32ABGRPixelFormat
k32RGBAPixelFormat
Once you've created a graphics world to your specifications, you can use it to set the current graphics port and device, then you can proceed to create your movie. The QTML function SetGWorld
void
SetGWorld
(CGrafPtr port, // Port or graphics world to make current
GDHandle gdh) // Device to make current
nominally accepts a graphics port and device record and makes them the current port and current device. However, if the port parameter actually points to a graphics world (remember that data types GWorldPtr and CGrafPtr are equivalent), then the function ignores parameter gdh and uses the port and device from the given graphics world instead. A companion function, GetGWorld
void
GetGWorld
(CGrafPtr *port, // Returns current port
GDHandle *gdh) // Returns current device
returns a pointer to the current port and a handle to the current device record. You can use this function, for example, to save the previous current port and device and restore them again after you're finished creating your movie. Listing 5 shows an example.
Listing 5 Using an offscreen graphics world
CGrafPtr oldPort; // Previous current port
GDHandle oldDevice; // Previous current device
GWorldPtr movieGWorld = nil; // Movie's graphics world
Rect movieFrame; // Boundary rectangle for movie images
OSErr errCode; // Result code
·
·
errCode = NewGWorld (&movieGWorld, // Return result in movieGWorld
16, // Pixel depth
&movieFrame, // Boundary rectangle
nil, // Use default color table
nil, // No preexisting device record
0 ); // No flags to pass
if ( errCode != noErr ) // Was there an error?
MessageBox (hWnd, "Error creating graphics world", "", MB_OK); // Notify user
else
{
GetGWorld (&oldPort, &oldDevice); // Save previous graphics world
SetGWorld (movieGWorld, nil); // Set movie's graphics world
/* Here...you would draw images */
SetGWorld (oldPort, oldDevice); // Restore previous graphics world
DisposeGWorld (movieGWorld); // Dispose of movie's graphics world
} /* end else */
Besides the general SetGWorld and GetGWorld functions, the QuickTime Movie Toolbox also provides a pair of functions for setting and retrieving a movie's graphics world directly:
void
SetMovieGWorld
(Movie theMovie,
CGrafPtr port,
GDHandle gdh)
void
GetMovieGWorld
(Movie theMovie,
CGrafPtr *port,
GDHandle *gdh)
This is useful for drawing offscreen because you can create GWorlds and then direct the movie to draw them there.
Like SetGWorld , SetMovieGWorld will accept a graphics world as its first parameter in place of a graphics port; it will then ignore the second parameter and use the device record from the graphics world instead.
| Previous | Chapter Contents | Chapter Top | Roadmap | Next |